package com.sky.orangehireserver.utils;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.function.Supplier;

/**
 * @description 虚拟线程工具类 ps: 虚拟线程在JDK21中正式发布 不需要额外参数就可以使用
 */
public class VirtualThreadUtil {

    /**
     * 创建一个【虚拟线程】的 Executor（每个任务一个虚拟线程）
     */
    public static ExecutorService newVirtualThreadExecutor() {
        return Executors.newVirtualThreadPerTaskExecutor();
    }
    /**
     * 异步运行一个任务（虚拟线程），返回 CompletableFuture
     */
    public static <T> CompletableFuture<T> runAsyncVirtual(Supplier<T> task) {
        ExecutorService executor = newVirtualThreadExecutor();
        // 注意：这里不关闭 executor，由调用方控制（或者使用 try-with-resources）
        return CompletableFuture.supplyAsync(task, executor);
    }
    /**
     * 异步运行一个无返回值的任务（虚拟线程）
     */
    public static CompletableFuture<Void> runAsyncVirtual(Runnable task) {
        ExecutorService executor = newVirtualThreadExecutor();
        return CompletableFuture.runAsync(task, executor);
    }

    /**
     * 提交一个无返回值的任务到虚拟线程
     */
    public static Future<Void> submitVirtual(Runnable task) {
        ExecutorService executor = newVirtualThreadExecutor();
        return executor.submit(task, null);
    }

    /**
     * 批量提交任务到虚拟线程，并等待所有完成（演示用，实际应使用 allOf 等组合）
     */
    public static void runBatchVirtualTasks(List<Runnable> tasks) throws Exception {
        ExecutorService executor = newVirtualThreadExecutor();

        List<Future<?>> futures = new ArrayList<>();
        for (Runnable task : tasks) {
            futures.add(executor.submit(task));
        }

        // 等待所有任务完成
        for (Future<?> future : futures) {
            future.get(); // 阻塞直到完成
        }

        executor.shutdown(); // 关闭 executor
    }

    /**
     * 快速异步执行（不关心结果，不阻塞）
     */
    public static void executeAsync(Runnable task) {
        Executors.newVirtualThreadPerTaskExecutor().submit(task);
    }
}
